# access configure (and eventually runtime) variables           -*-python-*-
# from Python
#
# use like so:
# import machinekit.config
# c = machinekit.config.Config()
# if c.is_rt():
#    ....
# define useful aggregate methods in Config() - this is preferrable to
# tests of raw config variables in usercode
#
# edit src/machinekitcfg.py-tmp.in
# run src/configure
# this will build lib/python/machinekit/config.py
#
# Author: Michael Haberler <license AT mah DOT priv DOT at>
# License: GPL Version 2 or later
# Copyright (c) 2013 All rights reserved.
import sys
if sys.version_info >= (3, 0):
    import configparser
else:
    import ConfigParser as configparser

_cfg = None  # global ConfigParser object


# type guessing helpers from http://stackoverflow.com/questions/7019283/automatically-type-cast-parameters-in-python
def __boolify(s):
    if s == 'True' or s == 'true':
        return True
    if s == 'False' or s == 'false':
        return False
    raise ValueError('Not Boolean Value!')


def __estimateType(var):
    '''guesses the str representation of the variables type'''
    for caster in (__boolify, int, float, str):
        try:
            return caster(var)
        except ValueError:
            pass
    return var


# loads a ini file to the config
def load_ini(iniName):
    global _cfg
    if _cfg is None:
        _cfg = configparser.ConfigParser()
    _cfg.read(iniName)


# find a config entry, compatible to linuxcnc.ini
# note: the module acts as singleton
def find(section, option, default=None):
    if _cfg is None:
        return default
    try:
        return __estimateType(_cfg.get(section, option))
    except (configparser.NoOptionError, configparser.NoSectionError):
        return default


class Config(object):

    def does_io(self):
        if self.BUILD_DRIVERS: return True

    # automatic substitution by configure starts here

    def __init__(self):
        self.GIT_VERSION = "@GIT_VERSION@"
        self.GIT_CONFIG_SHA="@GIT_CONFIG_SHA@"
        self.EMC2_HOME = "@EMC2_HOME@"
        self.BUILD_DRIVERS="@BUILD_DRIVERS@"
        self.SUBST="@BUILD_DRIVERS@"
        self.MACHINEKIT_INI="@MACHINEKIT_INI@"
        self.BUILD_THREAD_FLAVORS="@BUILD_THREAD_FLAVORS@"

        # Directories
        self.prefix="@prefix@"
        self.exec_prefix="@exec_prefix@"
        self.rundir= "@RUNDIR@"
        self.EMC2_HOME="@EMC2_HOME@"
        self.LIB_DIR="@EMC2_HOME@/lib"

        #used for install stuff
        #but have them here as reference
        #build system only uses EMC2_RTLIB_DIR when creating rtapi.ini
        self.EMC2_BIN_DIR="@EMC2_BIN_DIR@"
        self.EMC2_LIBEXEC_DIR="@EMC2_LIBEXEC_DIR@"
        self.EMC2_TCL_DIR="@EMC2_TCL_DIR@"
        self.EMC2_HELP_DIR="@EMC2_HELP_DIR@"
        self.EMC2_RTLIB_DIR="@EMC2_RTLIB_DIR@"
        self.EMC2_USER_CONFIG_DIR="~/emc2/configs"
        self.EMC2_SYSTEM_CONFIG_DIR="@EMC2_SYSTEM_CONFIG_DIR@"
        self.EMC2_NCFILES_DIR="@EMC2_NCFILES_DIR@"
        self.REALTIME="@REALTIME@"
        self.EMC2_IMAGEDIR="@EMC2_IMAGE_DIR@"


        # Standard configure directories
        # do we really need these?
        self.bindir = "@bindir@"
        self.sbindir = "@sbindir@"
        self.libexecdir = "@libexecdir@"
        self.datadir = "@datadir@"
        self.datarootdir = "@datarootdir@"
        self.sysconfdir = "@sysconfdir@"
        self.sharedstatedir = "@sharedstatedir@"
        self.localstatedir = "@localstatedir@"
        self.libdir = "@libdir@"
        self.infodir = "@infodir@"
        self.mandir = "@mandir@"
        self.includedir = "@includedir@"
        self.docdir = "@docdir@"
        self.sampleconfsdir = self.datadir + \
                              "/linuxcnc/examples/sample-configs"
        self.ncfilesdir = self.prefix + "/share/linuxcnc/ncfiles"
        self.tcldir = self.prefix + "/lib/tcltk/linuxcnc"


        # i18n variables:
        self.package = "@PACKAGE@"
        self.localedir = "@LOCALEDIR@"
        self.LANGUAGES = "@LANGUAGES@"


        # /Standard configure directories
        self.RUN_IN_PLACE = "@RUN_IN_PLACE@"
        self.CC = "@CC@"
        self.MANDB = "@MANDB@"
        self.HIDRAW_H_USABLE = "@HIDRAW_H_USABLE@"


        self.BUILD_DRIVERS = "@BUILD_DRIVERS@"
        self.USE_PORTABLE_PARPORT_IO = "@USE_PORTABLE_PARPORT_IO@"
        self.TARGET_PLATFORM_PC = "@TARGET_PLATFORM_PC@"
        self.TARGET_PLATFORM_BEAGLEBONE = "@TARGET_PLATFORM_BEAGLEBONE@"
        self.TARGET_PLATFORM_RASPBERRY = "@TARGET_PLATFORM_RASPBERRY@"
        self.ARCHITECTURE="@ARCHITECTURE@"

        self.USERMODE_PCI="@USERMODE_PCI@"

        #libudev for if USERMODE_PCI==yes
        self.LIBUDEV_CFLAGS="@LIBUDEV_CFLAGS@"
        self.LIBUDEV_LIBS="@LIBUDEV_LIBS@"

        # deps for xemc
        self.CFLAGS_X = "@X_CFLAGS@"
        self.XLIBS = "@XAW_LIBS@"
        self.HAVE_XAW = "@HAVE_XAW@"

        # ncurses support for keystick
        self.KEYSTICKLIBS =  "@NCURSES_LIBS@"
        self.HAVE_NCURSES = "@HAVE_NCURSES@"

        # readline support for halcmd
        self.READLINE_LIBS =  "@READLINE_LIBS@"

        # flags for glib
        self.GLIB_CFLAGS = "@GLIB_CFLAGS@"
        self.GLIB_LIBS = "@GLIB_LIBS@"

        # local flags for GTK include
        self.GTK_VERSION = "@GTK_VER@"
        self.GTK_CFLAGS = "@GTK_CFLAGS@"
        self.GTK_LIBS = "@GTK_LIBS@"
        self.HAVE_GNOMEPRINT = "@HAVE_GNOMEPRINT@"

        # tcl tk cflags, includes and libs
        self.TCL_DBGX="@TCL_DBGX@"
        self.TK_DBGX="@TK_DBGX@"
        self.TCL_CFLAGS="@TCL_CFLAGS@ @TK_CFLAGS@"
        self.TCL_LIBS="@TCL_LIBS@ @TK_LIBS@ @LIBS@"
        self.HAVE_WORKING_BLT="@HAVE_WORKING_BLT@"


        self.AR = "@AR@"
        self.ARFLAGS = "cr" #??
        self.CXX = "@CXX@"
        self.CXXFLAGS = "@CFLAGS@"
        self.RANLIB = "@RANLIB@"
        self.MSGFMT = "@MSGFMT@"
        self.XGETTEXT = "@XGETTEXT@"

        self.BUILD_DOCS = "@BUILD_DOCS@"
        self.BUILD_DOCS_PDF = "@BUILD_DOCS_PDF@"
        self.BUILD_DOCS_HTML = "@BUILD_DOCS_HTML@"
        self.PYTHON = "@PYTHON@"

#
# i18n
#
#       self.CONFIG_RTAPI=m

# # rtapi examples
#       self.CONFIG_RTAPI_EXAMPLES_EXTINT=m
#       self.CONFIG_RTAPI_EXAMPLES_FIFO=m
#       self.CONFIG_RTAPI_EXAMPLES_SEM=m
#       self.CONFIG_RTAPI_EXAMPLES_SHMEM=m
#       self.CONFIG_RTAPI_EXAMPLES_TIMER=m

# # emc motion module
#       self.CONFIG_MOTMOD=m

# # HAL components
#       self.CONFIG_BLOCKS=m
#       self.CONFIG_BOSS_PLC=m
#       self.CONFIG_DEBOUNCE=m
#       self.CONFIG_ENCODER=m
#       self.CONFIG_COUNTER=m
#       self.CONFIG_ENCODER_RATIO=m
#       self.CONFIG_STEPGEN=m
#       self.CONFIG_LCD=m
#       self.CONFIG_FREQGEN=m
#       self.CONFIG_PWMGEN=m
#       self.CONFIG_SIGGEN=m
#       self.CONFIG_AT_PID=m
#       self.CONFIG_PID=m
#       self.CONFIG_PEPPER=m
#       self.CONFIG_SUPPLY=m
#       self.CONFIG_CLASSICLADDER_RT=m
#       self.CONFIG_TIMEDELAY=m
#       self.CONFIG_SIM_ENCODER=m
#       self.CONFIG_WEIGHTED_SUM=m
#       self.CONFIG_WATCHDOG=m
#       self.CONFIG_MODMATH=m
#       self.CONFIG_STREAMER=m
#       self.CONFIG_SAMPLER=m

# # HAL drivers
#       self.CONFIG_HAL_PARPORT=m
#       self.CONFIG_PROBE_PARPORT=m
#       self.CONFIG_HAL_TIRO=m
#       self.CONFIG_HAL_EVOREG=m
#       self.CONFIG_HAL_MOTENC=m
#       self.CONFIG_HAL_SKELETON=m
#       self.CONFIG_HAL_GPIO=m
#       self.CONFIG_HAL_SPI=m
#       self.CONFIG_HAL_SPEAKER=m
#       self.CONFIG_HAL_STG=m
#       self.CONFIG_HAL_VTI=m
#       self.CONFIG_HAL_AX521H=m
#       self.CONFIG_HAL_PPMC=m
#       self.CONFIG_PCI_8255=m
#       self.CONFIG_HOSTMOT2=m
#       self.CONFIG_OPTO_AC5=m


        self.BUILD_PYTHON="@BUILD_PYTHON@"
        self.INCLUDEPY="@INCLUDEPY@"
        self.SITEPY="@SITEPY@"


# global Config exposes variable to module
__config = Config()
for attr in dir(__config):
    if not attr.startswith("__"):
        setattr(sys.modules[__name__], attr, getattr(__config, attr))
